function gadget:GetInfo()
  return {
    name      = "Torpedo Controller",
    desc      = "Controls movement to torpedoes",
    author    = "Rafal",
    date      = "Dec 2011",
    license   = "GNU GPL, v2 or later",
    layer     = 0,
    enabled   = true  --  loaded by default?
  }
end

--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

if (not gadgetHandler:IsSyncedCode()) then
  return
end
-- SYNCED

--------------------------------------------------------------------------------
-- CONFIG

local torpedoTravelDepth = -3.1  --less than -2 to get engine bubbles
local waterHitSpeedMult = 0.5
local calculateFlightTimes = true

--------------------------------------------------------------------------------

local scSetWatchWeapon           = Script.SetWatchWeapon
local spGetProjectileType        = Spring.GetProjectileType
local spGetProjectilePosition    = Spring.GetProjectilePosition
local spGetProjectileVelocity    = Spring.GetProjectileVelocity
local spGetProjectileGravity     = Spring.GetProjectileGravity
local spSetProjectilePosition    = Spring.SetProjectilePosition
local spSetProjectileVelocity    = Spring.SetProjectileVelocity
local spSetProjectileMoveControl = Spring.SetProjectileMoveControl

--------------------------------------------------------------------------------

local projectiles = {}
--[[
local spGetGameFrame = Spring.GetGameFrame
local spGetProjectileName = Spring.GetProjectileName
local spEcho = Spring.Echo
local sqrt = math.sqrt
local flightTimesToCalculate = {}
local flightTimeProjs = {}
--]]

function gadget:Initialize()
  for wdID, wd in ipairs(WeaponDefs) do
    if (wd.myCustomParams.isSpecialTorpedo) then
      scSetWatchWeapon(wdID, true)
    end  
  end
end

function gadget:ProjectileCreated (projID, projOwnerID)
  local isWeapon, _ = spGetProjectileType(projID)
  if (isWeapon) then
    local _posX, _posY, _posZ = spGetProjectilePosition(projID)
    local _velX, _velY, _velZ = spGetProjectileVelocity(projID)
    if (_posY <= torpedoTravelDepth) then
      spSetProjectileVelocity(projID, _velX, 0.0, _velZ) 
    else
      spSetProjectileMoveControl(projID, true)
      projectiles[projID] = {
        posX = _posX, posY = _posY, posZ = _posZ,
        velX = _velX, velY = 0    , velZ = _velZ,
        gravity = spGetProjectileGravity(projID)
      }
    end  
    --[[
    if (calculateFlightTimes) then
      local projName = spGetProjectileName(projID)
      if (not flightTimesToCalculate[projName]) then
        flightTimesToCalculate[projName] = true
        
        if (_posY <= torpedoTravelDepth) then
          spSetProjectileMoveControl(projID, true)
        end  
        flightTimeProjs[projID] = {
          name = projName,
          startFrame = spGetGameFrame(),
          startX = _posX,
          startZ = _posZ,
          range = WeaponDefNames[projName].range,
          notInWater = (_posY > -3.0),
        }
      end    
    end
    --]]
  end
end


function gadget:ProjectileDestroyed (projID) 
  projectiles[projID] = nil
  --[[
  if (flightTimeProjs[projID]) then
    local projName = flightTimeProjs[projID].name
    flightTimesToCalculate[projName] = nil
    flightTimeProjs[projID] = nil
  end
  --]]
end


function gadget:GameFrame (frameNum)
  for projID, proj in pairs(projectiles) do
    proj.velY = proj.velY + proj.gravity
    proj.posX = proj.posX + proj.velX
    proj.posY = proj.posY + proj.velY
    proj.posZ = proj.posZ + proj.velZ
    proj.velX = proj.velX * 0.98
    proj.velY = proj.velY * 0.98
    proj.velZ = proj.velZ * 0.98    
    if (proj.posY <= torpedoTravelDepth) then
      proj.posY = torpedoTravelDepth
      spSetProjectilePosition(projID, proj.posX, proj.posY, proj.posZ)
      spSetProjectileVelocity(projID, proj.velX * waterHitSpeedMult, 0.0, proj.velZ * waterHitSpeedMult)  --seems that its value is ignored, only direction matters
      spSetProjectileMoveControl(projID, false)
      projectiles[projID] = nil
    else
      spSetProjectilePosition(projID, proj.posX, proj.posY, proj.posZ)
    end
  end 
  --[[
  for projID, proj in pairs(flightTimeProjs) do
    local posX, posY, posZ = spGetProjectilePosition(projID) 
    if (proj.notInWater and not (posY > -3.0)) then
      spEcho(proj.name:upper() .. " starts traveling in water after " .. tostring(frameNum - proj.startFrame) .. " frames")
      proj.startFrame = frameNum
      proj.notInWater = false
    end
    
    local dx = posX - proj.startX
    local dz = posZ - proj.startZ
    local distance = math.sqrt(dx * dx + dz * dz)
    
    if (distance > proj.range) then
      local lastFrame = frameNum - 1
      local flightTime = (lastFrame - proj.startFrame + 0.5) / 32  --not GAME_SPEED
      spEcho(proj.name:upper() .. " calculated flightTime: " .. tostring(flightTime))
      flightTimeProjs[projID] = nil
    end
  end
  --]]
end

-- SYNCED